﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using Baosight.Platform.Core;
using Telerik.Windows.Controls.GridView;
using Baosight.Platform.Core.UI.Controls;
using System.ComponentModel;
using Telerik.Windows.Controls;
using Baosight.Platform.Core.ServiceModel;
using Baosight.Platform.Core.UI;

namespace Baosight.ZNH.ZMCommon
{

    public partial class CmesUpload : UserControl
    {
        #region DependencyProperties

        /// <summary>
        /// 获取或设置上传对应的后台服务地址
        /// </summary>
        public string eServiceUrl
        {
            get { return (string)GetValue(ServiceUrlProperty); }
            set { SetValue(ServiceUrlProperty, value); }

        }
        public static readonly DependencyProperty ServiceUrlProperty =
                DependencyProperty.Register(
                "eServiceUrl",
                typeof(string),
                typeof(CmesUpload),
                new PropertyMetadata("./ApacheFileUploadServlet", null));

        /// <summary>
        /// 获取或设置文件选择器支持文件后缀名
        /// </summary>
        public string eFilter
        {
            get { return (string)GetValue(FilterProperty); }
            set { SetValue(FilterProperty, value); }

        }
        public static readonly DependencyProperty FilterProperty =
                DependencyProperty.Register(
                "eFilter",
                typeof(string),
                typeof(CmesUpload),
                new PropertyMetadata("", OnFilterPropertyChanged));

        private static void OnFilterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            CmesUpload upload = d as CmesUpload;
            if (upload.Dialog == null)
            {
                upload.Dialog = new OpenFileDialog();
            }
            if (e.NewValue == null)
            {
                upload.Dialog.Filter = "All Files(*.*)|*.*";
            }
            else
            {
                upload.Dialog.Filter = e.NewValue.ToString();
            }
        }

        /// <summary>
        /// 获取或设置文件后缀名过滤索引
        /// </summary>
        public int eFilterIndex
        {
            get { return (int)GetValue(FilterIndexProperty); }
            set { SetValue(FilterIndexProperty, value); }

        }
        public static readonly DependencyProperty FilterIndexProperty =
                DependencyProperty.Register(
                "eFilterIndex",
                typeof(int),
                typeof(CmesUpload),
                new PropertyMetadata(0, OnFilterIndexPropertyChanged));

        private static void OnFilterIndexPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            CmesUpload upload = d as CmesUpload;
            if (upload.Dialog == null)
            {
                upload.Dialog = new OpenFileDialog();
            }
            if (e.NewValue != null)
            {
                upload.Dialog.FilterIndex = (int)e.NewValue;
            }
        }

        /// <summary>
        /// 获取或设置文件选择器支持文件后缀名
        /// </summary>
        public bool eIsMultiselect
        {
            get { return (bool)GetValue(IsMultiselectProperty); }
            set { SetValue(IsMultiselectProperty, value); }

        }
        public static readonly DependencyProperty IsMultiselectProperty =
                DependencyProperty.Register(
                "eIsMultiselect",
                typeof(bool),
                typeof(CmesUpload),
                new PropertyMetadata(false, OnIsMultiselectPropertyChanged));

        private static void OnIsMultiselectPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            CmesUpload upload = d as CmesUpload;
            if (upload.Dialog == null)
            {
                upload.Dialog = new OpenFileDialog();
            }
            bool isMultiselect = (bool)e.NewValue;
            upload.Dialog.Multiselect = isMultiselect;
        }

        /// <summary>
        /// 获取或设置上传文件的最大个数
        /// </summary>
        public int eMaxFileCount
        {
            get { return (int)GetValue(MaxFileCountProperty); }
            set { SetValue(MaxFileCountProperty, value); }

        }
        public static readonly DependencyProperty MaxFileCountProperty =
                DependencyProperty.Register(
                "eMaxFileCount",
                typeof(int),
                typeof(CmesUpload),
                new PropertyMetadata(5, null));

        /// <summary>
        /// 获取或设置单个上传文件的最大大小配置
        /// </summary>
        [TypeConverter(typeof(StringToLongTypeConverter))]
        public long eMaxFileSize
        {
            get { return (long)GetValue(MaxFileSizeProperty); }
            set { SetValue(MaxFileSizeProperty, value); }

        }
        public static readonly DependencyProperty MaxFileSizeProperty =
                DependencyProperty.Register(
                "eMaxFileSize",
                typeof(long),
                typeof(CmesUpload),
                new PropertyMetadata(long.Parse("102400000"), null));

        /// <summary>
        /// 获取或设置总共上传文件的大小
        /// </summary>
        [TypeConverter(typeof(StringToLongTypeConverter))]
        public long eMaxUploadSize
        {
            get { return (long)GetValue(MaxUploadSizeProperty); }
            set { SetValue(MaxUploadSizeProperty, value); }

        }
        public static readonly DependencyProperty MaxUploadSizeProperty =
                DependencyProperty.Register(
                "eMaxUploadSize",
                typeof(long),
                typeof(CmesUpload),
                new PropertyMetadata(long.Parse("204800000"), null));

        /// <summary>
        /// 获取或设置文件列表对应的Block
        /// </summary>
        public string eBlockName
        {
            get { return (string)GetValue(BlockNameProperty); }
            set { SetValue(BlockNameProperty, value); }

        }
        public static readonly DependencyProperty BlockNameProperty =
                DependencyProperty.Register(
                "eBlockName",
                typeof(string),
                typeof(CmesUpload),
                new PropertyMetadata("file_info", OnBlockNamePropertyChanged));

        private static void OnBlockNamePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != null && e.NewValue != null)
            {
                CmesUpload upload = d as CmesUpload;
                if (upload.grid != null)
                {
                    upload.grid.eBlockName = e.NewValue.ToString();
                }
            }
        }
        #endregion

        #region property
        /// <summary>
        /// 是否上传完毕
        /// </summary>
        public bool IsBusy
        {
            get { return busyIndicator.IsBusy; }
            set { busyIndicator.IsBusy = value; }
        }

        /// <summary>
        /// 定义弹出选择文件的对话框
        /// </summary>
        private OpenFileDialog dialog;
        public OpenFileDialog Dialog
        {
            get { return dialog; }
            set { dialog = value; }
        }

        /// <summary>
        /// 获取文件列表中有几条数据
        /// </summary>
        public int GridRowCount
        {
            get { return this.grid.HasItems ? this.grid.Items.Count : 0; }
        }

        /// <summary>
        /// 上传器
        /// </summary>
        private Uploader uploader;
        public Uploader Uploader
        {
            get
            {
                if (uploader == null)
                {
                    uploader = new Uploader(this.eServiceUrl);
                }
                return uploader;
            }
            set { uploader = value; }
        }

        /// <summary>
        /// 上传的文件字典:文件名--文件ID
        /// </summary>
        public Dictionary<string, string> InsertFileArgs
        {
            get { return this.Uploader.ResponseFileId; }
        }

        private int Index = 0;//记录EFGrid中已经存在多少条文件信息  

        //下面是文件列表中的列名
        private string fdKeyId = "fdKeyId";
        private string fdFileName = "fdFileName";
        private string fdMemoryName = "fdMemoryName";
        private string fdFileSize = "fdFileSize";
        private string fdForeignId = "fdForeignId";

        private HyperlinkButton DeleteButton;//临时记录删除按钮

        #endregion



        public CmesUpload()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AddFile_Click(object sender, RoutedEventArgs e)
        {
            errorTip.Visibility = Visibility.Collapsed;

            if (Dialog.ShowDialog().Value)
            {
                Index = this.grid.HasItems ? this.grid.Items.Count : 0;
                if ((this.GridRowCount + dialog.Files.Count()) > this.eMaxFileCount)
                {
                    ShowErrorTip("最多只能上传" + this.eMaxFileCount + "个文件！");
                    IsBusy = false;
                    return;
                }

                foreach (FileInfo file in dialog.Files)
                {
                    try
                    {
                        //判断文件是否被打开
                        Stream oFileStream = file.OpenRead();
                        oFileStream.Close();

                        if (Uploader.AllFilesLength > this.eMaxUploadSize)
                        {
                            ShowErrorTip("文件总大小不能超过" + Convert(this.eMaxUploadSize) + "！");
                            Uploader.Files.Clear();
                            IsBusy = false;
                            return;
                        }
                        if (file.Length > this.eMaxFileSize)
                        {
                            ShowErrorTip("文件" + file.Name + "的大小不能超过" + Convert(this.eMaxFileSize) + "！");
                            Uploader.Files.Clear();
                            IsBusy = false;
                            return;
                        }
                        if (!file.Extension.Equals("exe"))
                        {
                            UploadFile uploadFile = new UploadFile(file);
                            if (!Uploader.Contains(uploadFile))
                            {
                                Uploader.AddFile(uploadFile);
                                ShowFileList(uploadFile);
                            }
                        }
                    }
                    catch (IOException ex)
                    {
                        ShowErrorTip(ex.Message);
                    }                    
                }
                //有上传文件在设置BUSY状态
                if (uploader != null)
                {
                    IsBusy = true;
                }

                this.grid.UpdateLayout();
                Uploader.UploadResponsed += new EventHandler<EventArgs>(Uploader_UploadResponsed);

                UpdateImageData(FileUploadStatus.Pending);
                Uploader.Upload();
            }
            else
            {
                BaseTools.OpenEFWindowAlert("没有选择文件，请重新选择文件！", null);
                IsBusy = false;
            }
        }

        /// <summary>
        /// 显示错误提示框
        /// </summary>
        /// <param name="error">已经包含了超过单个文件的最大值的文件名</param>
        /// <param name="count">上传的实际文件个数</param>
        /// <param name="flag">是否超过上传的总大小</param>
        private void ShowErrorTip(string error)
        {
            if (!error.Equals(""))
            {
                errorTip.Visibility = Visibility.Visible;
                errorContent.Text = error;
            }
        }

        /// <summary>
        /// 将要上传的文件展示在列表中
        /// </summary>
        /// <param name="uploader"></param>
        private void ShowFileList(UploadFile file)
        {
            EIBlock block = this.grid.EIBlock;
            EIRow row = new EIRow();

            row.Add(fdKeyId, "");
            row.Add(fdFileName, file.FileName);
            row.Add(fdFileSize, Convert(file.FileLength));
            row.Add(fdMemoryName, "");
            row.Add(fdForeignId, "");
            block.AddRow(row);
        }

        /// <summary>
        /// 设置文件不同状态时，列表中显示不同的图片
        /// </summary>
        /// <param name="status"></param>
        /// <param name="cell"></param>
        private void SetStautsImage(FileUploadStatus status, GridViewCell cell)
        {
            switch (status)
            {
                case FileUploadStatus.Pending:
                    Image img = cell.GetChildObject<Image>("completeImage");
                    img.Visibility = Visibility.Collapsed;
                    img = cell.GetChildObject<Image>("pendingImage");
                    img.Visibility = Visibility.Visible;
                    break;
                case FileUploadStatus.Complete:
                    img = cell.GetChildObject<Image>("pendingImage");
                    img.Visibility = Visibility.Collapsed;
                    img = cell.GetChildObject<Image>("completeImage");
                    img.Visibility = Visibility.Visible;
                    break;
                case FileUploadStatus.Error:
                    img = cell.GetChildObject<Image>("pendingImage");
                    img.Visibility = Visibility.Collapsed;
                    img = cell.GetChildObject<Image>("errorImage");
                    img.Visibility = Visibility.Visible;
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 根据状态变换图片
        /// </summary>
        /// <param name="status"></param>
        private void UpdateImageData(FileUploadStatus status)
        {
            if (this.grid.Items == null)
            {
                return;
            }
            for (int i = Index; i < this.grid.Items.Count; i++)
            {
                GridViewRow gridRow = this.grid.ItemContainerGenerator.ContainerFromIndex(i) as GridViewRow;
                if (gridRow != null)
                {
                    GridViewCell cell = gridRow.Cells[0] as GridViewCell;
                    SetStautsImage(status, cell);
                }
            }
        }

        /// <summary>
        /// 上传完毕后Responsed响应后触发的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Uploader_UploadResponsed(object sender, EventArgs e)
        {
            if (Uploader.IsComplete)
            {
                //UpdateImageData(FileUploadStatus.Complete);
                EIBlock block = this.grid.EIBlock;
                foreach (EIRow row in block.GetRows())
                {
                    foreach (string key in Uploader.ResponseFileId.Keys)
                    {
                        if (row[fdFileName].ToString().Equals(key.Substring(14)))
                        {
                            row[fdKeyId] = Uploader.ResponseFileId[key];
                            row[fdMemoryName] = key;
                        }
                    }
                }
                UpdateImageData(FileUploadStatus.Complete);
            }
            else
            {
                UpdateImageData(FileUploadStatus.Error);
            }
            IsBusy = false;
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
        {
            DeleteButton = sender as HyperlinkButton;
            BaseTools.OpenEFWindowConfirm("确定要删除该文件吗？", WindowConfirmClosed);
        }

        /// <summary>
        /// 确认要删除的回调方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WindowConfirmClosed(object sender, WindowClosedEventArgs e)
        {
            if (e.DialogResult == null)
            {
                return;
            }
            if (e.DialogResult.Value)
            {
                EIRow EiRow = (DeleteButton.ParentOfType<GridViewRow>().Item as UIBaseEntity).GetEIRow();                

                EIInfo info = new EIInfo();
                info.Attributes.Add(EIConstants.ServiceNameKey, "ZMCD05");
                info.Attributes.Add(EIConstants.MethodNameKey, "delete");
                EIBlock block = info.AddBlock(EIConstants.ResultBlock);

                EIColumn column = new EIColumn();
                column.Name = "fdKeyId";
                block.AddColumn(column);

                column = new EIColumn();
                column.Name = "fdMemoryName";
                block.AddColumn(column);

                EIRow row1 = new EIRow();
                row1.Add("fdKeyId", EiRow["fdKeyId"]);
                row1.Add("fdMemoryName", EiRow["fdMemoryName"]);
                block.AddRow(row1);

                HttpServiceAgent agent = new HttpServiceAgent();
                agent.CallService(info, OnDoWorkCompleted);
            }
        }

        /// <summary>
        /// 从后台删除完文件后的回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnDoWorkCompleted(object sender, DoWorkCompletedEventArgs e)
        {
            if (e.EIInfo.GetStatus() != -1)
            {                
                EIRow EiRow = (DeleteButton.ParentOfType<GridViewRow>().Item as UIBaseEntity).GetEIRow();
                Uploader.Remove(EiRow["fdFileName"].ToString());
                Uploader.ResponseFileId.Remove(EiRow["fdMemoryName"].ToString());
                this.grid.Items.Remove(DeleteButton.ParentOfType<GridViewRow>().Item);
            }
        }

        /// <summary>
        /// 字节转换为Kb,Mb,Gb
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        private object Convert(object value)
        {
            string size = "0 KB";

            if (value != null)
            {
                long byteCount = (long)value;

                if (byteCount >= 1073741824)
                    size = String.Format("{0:##.##}", (double)byteCount / 1073741824) + " GB";
                else if (byteCount >= 1048576)
                    size = String.Format("{0:##.##}", (double)byteCount / 1048576) + " MB";
                else if (byteCount >= 1024)
                    size = String.Format("{0:##.##}", (double)byteCount / 1024) + " KB";
                else if (byteCount > 0 && byteCount < 1024)
                    size = "1 KB";    //Bytes are unimportant ;)            

            }

            return size;
        }


    }




    public enum FileUploadStatus
    {
        Pending,
        Complete,
        Error
    }
}
